Skip to content

MOVUPD:非对齐打包双精度数据移动

MOVUPD 是 SSE2 的非对齐 128 位复制指令。它与 MOVAPD 搬运相同数量的数据,但内存操作数可以从非 16 字节边界开始。

操作码
66 0F 10 /r
指令集
SSE2
英文全称
Move Unaligned Packed Double-Precision Floating-Point Values
参考资料
INTEL SDM
页码
4-123
01MOVUPD02xmm003xmm1/m128
01
指令助记符MOVUPDmnemonic

Move Unaligned Packed Double-Precision Floating-Point Values,从寄存器或任意字节边界复制 128 位。

02
目标寄存器xmm0destination

接收源 XMM 寄存器或 128 位内存中的全部位。

03
源操作数xmm1/m128source

内存源不必位于 16 字节边界。

操作码
66 0F 11 /r
指令集
SSE2
英文全称
Move Unaligned Packed Double-Precision Floating-Point Values
参考资料
INTEL SDM
页码
4-123
01MOVUPD02xmm1/m12803xmm0
01
指令助记符MOVUPDmnemonic

存储形式将 XMM 寄存器中的 128 位原样写入寄存器或内存目标。

02
目标操作数xmm1/m128destination

内存目标不必位于 16 字节边界。

03
源寄存器xmm0source

提供要写入目标的全部 128 位。

非对齐访问

下图直接绘制完整的 128 位数据。MOVUPD 允许内存地址不满足 16 字节对齐;LOADSTORE 只改变复制方向。

MOVUPD · PACKED BIT COPY · 128 BITS2 × FLOAT64
允许非 16 字节对齐内存
m128(内存)128 BITS
m128[127:0]
m128[1]2FLOAT64
m128[0]1FLOAT64
xmm0128 BITS
xmm0[127:0]
xmm0[1]2FLOAT64
xmm0[0]1FLOAT64
每个圆球代表一个 FLOAT64 元素强调背景:复制目标图中高索引在左、低索引在右
text
load:  XMM_DEST[127:0] = SRC[127:0]
store: DEST[127:0]     = XMM_SRC[127:0]

“允许非对齐”只表示不会因为地址不是 16 字节倍数而产生 MOVAPD 的对齐 #GP。地址仍须有效并具有相应访问权限,跨越未映射页面时仍可能发生页故障。

汇编示例

asm
section .data
align 16
storage:      db 0
unaligned_pd: dq 1.5, -2.0
output:       times 32 db 0

section .text
movupd xmm0, [unaligned_pd]  ; 66 0F 10:地址可以非 16 字节对齐
movupd [output + 3], xmm0    ; 66 0F 11:非对齐存储

这两个内存操作数不要求地址按 16 字节对齐。在部分微架构上,跨越缓存行或页面边界的非对齐访问可能比单一边界内的访问代价更高。

与 MOVAPD 的区别

指令传统 XMM 内存宽度16 字节对齐要求加载操作码存储操作码
MOVAPD128 位必须66 0F 28 /r66 0F 29 /r
MOVUPD128 位不要求66 0F 10 /r66 0F 11 /r

两者用于寄存器到寄存器复制时,得到的 128 位结果相同。VEX 形式 VMOVUPD 支持 XMM/YMM,EVEX 形式还支持 ZMM 和写掩码;VEX/EVEX 写入 XMM 或 YMM 目标时会清零对应目标寄存器的更高位。

MOVUPD 不修改 EFLAGS,也不产生 SIMD 浮点异常。

参考

SIGNAL MAINTAINED · BUILT FROM MARKDOWN